#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import cv2
import cgi
import html
import http.server
import sys
import requests
import os
import socket
import cgitb 
import os
import cgitb; cgitb.enable()
from imutils.video import VideoStream
import shutil
import time
import face_recognition
import numpy as np
import pickle
import sqlite3
import datetime
from collections import Counter
import base64
from os import walk
from PIL import Image, ImageDraw, ImageFont

'''
   обрабатываем http внешний запрос, получаем номер ip камеры для обработки 
'''
IP_ADR =[]
print("Content-type: text/html\n")
print("""<!DOCTYPE HTML>
        <html>
        <head>
            <meta charset="utf-8">
        </head>
        <body>
""")
form = cgi.FieldStorage()
IP_ADR = form.getfirst("ip_adr", "aa")
if IP_ADR in ["aa"]:
   print("no ip_adr")
   sys.exit()
   
known_face_encodings =[]
known_face_names = []
img=[]
frame=[]
frames=[]

log_file = open("face-cgi.log", "a") '''  название log файла '''
videostream = "rtsp://"+IP_ADR.strip()+":554/ch01/0"  '''  запрос к ip кмере для получения потока '''

vs = VideoStream(src=videostream).start()    ''' активация  ip камеры  '''
def load_known_faces():               ''' получение массиввов имя -Ю матрица лица из файла faces_46.dat '''
    global known_face_encodings, known_face_names
    try:
        with open("cgi-bin/faces_46.dat", "rb") as face_data_file:
            known_face_encodings, known_face_names = pickle.load(face_data_file)
    except FileNotFoundError as e:       
        sys.exit();
        pass

load_known_faces()
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
alt_face_distances = []
index = []
names =" "
best_match_index = 0
t=0

start_time = datetime.datetime.now()
start_time_max = datetime.datetime.now()
name = "00000"

img_pil = Image.fromarray(vs.read())
img = np.array(img_pil)
foto_data = str(datetime.datetime.now())
cv2.imwrite('/foto/'+ foto_data +'_Enter.jpg',img)  ''' куда будем складывать полученые с камкры кадры  '''
img_pil =[]
img=[]
intera=0
en_f =0 
ind = " "
log_file.write(" "+'\n') 
while True:            ''' бесконечный цикл получения обработки сравнения ввычисления эвкл. растояния анадиза и выход из цикла  '''
   frame = vs.read()
   t=0 
   en_f = 0
   start_tim0 = datetime.datetime.now()  ''' необходимо для выхода из цикла нсли прошло время  '''
   small_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)     ''' получение кадра, сжатие можно и не делать всё зависит от камеры '''
   face_locations=[]
   face_locations = face_recognition.face_locations(small_frame)   ''' есть ли лица в кадре   '''
   en_f =  len(face_locations) 
   if len(face_locations) > 1:
        print("*#*-000000*#*")  ''' еслиибольше дух человек  '''
        
        face_encodings = face_recognition.face_encodings(small_frame, face_locations) 
        for face_encoding in face_encodings:
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            name = "-000000"
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]  ''' определяем кто они  '''
            face_names.append(name)

        #for (top, right, bottom, left) in (face_locations):
        for (top, right, bottom, left) , name in zip(face_locations, face_names):  ''' рисуем рамку, пишем номер '''
            top *= 2
            right *=2 
            bottom *= 2
            left *= 2
            cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
            cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
            font = cv2.FONT_HERSHEY_DUPLEX
            cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)      
        cv2.imwrite('/foto/'+ foto_data +'_Больше_одного_000000.jpg',frame) 
        data_uri = base64.b64encode(open('/foto/'+ foto_data +'_Больше_одного_000000.jpg','rb').read()).decode('utf-8').replace('\n', '')
        img_tag = '<img src="data:image/png;base64,%s" width="900" height="450" alt="" >' % data_uri
        #log_file.write('\n'+ foto_data+' _Больше одного \n')
        print(img_tag)  ''' возвращаем код много лиц и изображение '''
        time.sleep(1)  ''' пауза для ожидания передачи img '''
        quit()


   if face_locations:   # если лицо в кадре есть и оно одно - иначе сработал бы код выше 
     face_encodings = face_recognition.face_encodings(small_frame, face_locations)  
     for face_encoding in face_encodings: #  перебрать все массивы лиц в базе и определить дистанцию с пролученым масивом
             face_compare = face_recognition.compare_faces( known_face_encodings , face_encoding, tolerance=0.5 )
             dis = np.where(face_compare)[0] # получаем массив 
             intera =   intera +1
             log_file.write(str(datetime.datetime.now())+"  intera-"+str( intera)+"  dis-"+str(dis) +'\n')
             '''       
              intera-1  dis-[ 60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75 495 497500 501 502 503 504 505 507 508 509 511]
              2024-06-05 08:09:59.904774  60,  intera-1 60 003162==>['003162']
              2024-06-05 08:09:59.904801  60,61,  intera-1 61 003162==>['003162', '003162']
              2024-06-05 08:09:59.904820  60,61,62,  intera-1 62 003162==>['003162', '003162', '003162']
              2024-06-05 08:09:59.904837  60,61,62,63,  intera-1 63 003162==>['003162', '003162', '003162', '003162']
              2024-06-05 08:09:59.904855  60,61,62,63,64,  intera-1 64 003162==>['003162', '003162', '003162', '003162', '003162']
             '''
             for dis_x in dis: 
                ind = ind + str(dis_x)+ "," 
                kol=[]
                index.append(known_face_names[dis_x])
                kol = Counter(index).most_common()
                log_file.write(str(datetime.datetime.now())+" "+ind +"  intera-"+str( intera)+" "+  str(dis_x)+ " "+str(known_face_names[dis_x])+"==>" + str(index) +'\n')           
                if kol[0][1]>4:  
                    name = kol[0][0]
                    print("*#* ",name," *#*")
                    img_pil = Image.fromarray(frame)
                    img = np.array(img_pil)
                    cv2.imwrite('cgi-bin/foto/'+ name+"_"+str(foto_data)+'_ok_.jpg',img)   
                    try:
                      data_uri = base64.b64encode(open("//home/cam/cammIP/N_F/"+name+"/"+name+".jpg", 'rb').read()).decode('utf-8').replace('\n', '')
                      img_tag = '<img src="data:image/png;base64,%s" width="200" height="250" alt="" >' % data_uri
                      print(img_tag)
                    except:
                      pass
                    index =[]
                    dis=[]
                    quit();                      
  
   end_time_max = datetime.datetime.now()
   delta_time_max = end_time_max - start_time_max

   if int((str(delta_time_max).split(":")[2]).split(".")[0]) >3:    
         log_file.close()
         log_file = open("face-cgi.log", "a")

         if en_f >0: 
           cv2.imwrite('/foto/'+ str(datetime.datetime.now()) +'_Не_смог_определить_000000.jpg',frame)
           log_file.write( str(datetime.datetime.now()) + " _Не_смог_определить_000000"+ '\n')
           print("*#*000000*#*")

 
         else: 
           cv2.imwrite('/foto/'+ str(datetime.datetime.now()) +'_Пустой_кадр_-000001.jpg',frame)
           log_file.write( str(datetime.datetime.now())+" Пустой_кадр_-000001"+ '\n')
           print("*#*-000001*#*")
         #time.sleep(1)
         quit()


quit()






 